<template>
  <div :id="FORM_WRAPPER_ID">
    <component
      :is="isDrawer ? Drawer : Modal"
      v-bind="props.option.formWrapper"
      :title="() => formTitle"
      :show="formVisible"
      :action-id="isDrawer ? DRAWER_ACTION_ID : MODAL_ACTION_ID"
      @update:show="onUpdateFormShow"
    >
      <NvForm
        ref="formRef"
        v-model:form="form"
        v-model:loading="submitLoading"
        :option="formOption"
        :mode="formMode"
        @submit="handleSubmit"
      >
        <template v-for="(_, name) in slots" #[name]="slotData">
          <slot :name v-bind="slotData || {}" />
        </template>
      </NvForm>
    </component>
  </div>
</template>

<script setup lang="tsx">
import type { Emits, Expose, Props } from './types'
import type { NvFormInst } from '@/form/types'
import type { RowData } from '@/types'
import { ref } from 'vue'
import NvForm from '@/form/Index.vue'
import { useForm } from './use-form'
import { Drawer, Modal } from './wrapper'

const props = defineProps<Props>()
const emits = defineEmits<Emits>()
const slots = defineSlots()

const form = defineModel<RowData>('form', { required: true })
const formVisible = defineModel<boolean>('formVisible', { required: true })
const submitLoading = defineModel<boolean>('submitLoading', { required: true })

const {
  isDrawer, formTitle, formOption,
  FORM_WRAPPER_ID, DRAWER_ACTION_ID, MODAL_ACTION_ID,
  onUpdateFormShow, openForm, closeForm, handleSubmit,
} = useForm(props, emits, form, formVisible)

const formRef = ref<NvFormInst>()

const expose = {
  openForm,
  closeForm,
  validate: ((...args) => formRef.value!.validate(...args)) as NvFormInst['validate'],
  restoreValidation: () => formRef.value!.restoreValidation(),
  clear: () => formRef.value!.clear(),
  submit: () => formRef.value!.submit(),
  prevStep: () => formRef.value!.prevStep(),
  nextStep: () => formRef.value!.nextStep(),
}

defineExpose<Expose>(expose)
</script>
